package basic

import (
	"fmt"
	"golang.org/x/sync/errgroup"
	"net/http"
	"sync"
)

var d int
var m sync.Mutex

type singleton struct{}

var once sync.Once

func Channel() {
	//声明 var a chan []int
	//初始化
	//a := make(chan []int, 10)
	//发送 a <- 10
	//接受 x <- a
	//关闭close(a)

	//无缓存区和有缓存区通道
	//无缓存区必须有goroutine接受，否则会阻塞。又称同步通道
	//todo 发送方记得关闭chan 否则会panic for range 没close会死锁

	//单向通道

	//select

	//c1 := make(chan int, 100)
	//c2 := make(chan int, 200)
	//
	//go f11(c1)
	//go f22(c1, c2)
	//select {
	//case xx := <-c2:
	//	fmt.Print(xx)
	//}

	//并发安全（锁）
	//互斥锁
	//wg.Add(2)
	//go f33()
	//go f33()
	//wg.Wait()
	//fmt.Print(d)

	//任务同步sync.WaitGroup 防止主进程都走完了，goroutine还没结束

	//sync.Once 只加载一次 单例 配置文件
	getInstance()
	go getInstance()
	fmt.Print(instance)

	//sync.Map

	//errgroup
	g := new(errgroup.Group)

	var urls = []string{
		"http://pkg.go.dev",
		"http://www.liwenzhou.com",
		"http://www.yixieqitawangzhi.com",
	}
	for _, url := range urls {
		g.Go(func() error {
			resp, err := http.Get(url)
			if err == nil {
				resp.Body.Close()
			}
			return err
		})
	}

	err := g.Wait()
	if err != nil {
		// 处理可能出现的错误
		fmt.Println(err)
		return
	}
	fmt.Print("成功")

}

var instance *singleton

func getInstance() {
	fmt.Print(11)
	once.Do(func() {
		fmt.Print(22)
		instance = &singleton{}
	})
}

func f11(c1 chan<- int) {
	for i := 0; i < 100; i++ {
		c1 <- i
	}
}

func f22(c1 <-chan int, c2 chan<- int) {
	for {
		v, ok := <-c1
		if !ok {
			break
		}
		c2 <- v * v
	}
}

func f33() {
	for i := 0; i < 5000; i++ {
		m.Lock()
		d = d + 1
		m.Unlock()
	}
	wg.Done()
}
